package com.lifeverse.repository;

import com.lifeverse.entity.LearningExperience;
import com.lifeverse.entity.enums.ExperienceType;
import com.lifeverse.entity.enums.LearningOutcome;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 学习经验数据访问接口
 */
@Repository
public interface LearningExperienceRepository extends JpaRepository<LearningExperience, Long> {

    /**
     * 根据生命体ID查找学习经验
     */
    List<LearningExperience> findByLifeEntityId(Long lifeEntityId);

    /**
     * 根据生命体ID和经验类型查找学习经验
     */
    List<LearningExperience> findByLifeEntityIdAndExperienceType(Long lifeEntityId, ExperienceType experienceType);

    /**
     * 根据学习结果查找经验
     */
    List<LearningExperience> findByOutcome(LearningOutcome outcome);

    /**
     * 查找高效率的学习经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.efficiency >= :minEfficiency ORDER BY le.efficiency DESC")
    List<LearningExperience> findHighEfficiencyExperiences(@Param("lifeEntityId") Long lifeEntityId, 
                                                           @Param("minEfficiency") Double minEfficiency);

    /**
     * 查找最近的学习经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.startedAt >= :since ORDER BY le.startedAt DESC")
    List<LearningExperience> findRecentExperiences(@Param("lifeEntityId") Long lifeEntityId, 
                                                   @Param("since") LocalDateTime since);

    /**
     * 根据重要性评分查找经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.importanceScore >= :minImportance ORDER BY le.importanceScore DESC")
    List<LearningExperience> findImportantExperiences(@Param("lifeEntityId") Long lifeEntityId, 
                                                      @Param("minImportance") Double minImportance);

    /**
     * 查找需要强化的经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.retentionRate < :maxRetention AND le.importanceScore > :minImportance")
    List<LearningExperience> findExperiencesNeedingReinforcement(@Param("lifeEntityId") Long lifeEntityId,
                                                                @Param("maxRetention") Double maxRetention,
                                                                @Param("minImportance") Double minImportance);

    /**
     * 分页查询生命体的学习经验
     */
    Page<LearningExperience> findByLifeEntityId(Long lifeEntityId, Pageable pageable);

    /**
     * 统计学习经验数量
     */
    @Query("SELECT COUNT(le) FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.outcome = :outcome")
    Long countByLifeEntityIdAndOutcome(@Param("lifeEntityId") Long lifeEntityId, @Param("outcome") LearningOutcome outcome);

    /**
     * 计算平均学习效率
     */
    @Query("SELECT AVG(le.efficiency) FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.startedAt >= :since")
    Double calculateAverageEfficiency(@Param("lifeEntityId") Long lifeEntityId, @Param("since") LocalDateTime since);

    /**
     * 查找相似的学习经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND le.experienceType = :type AND le.difficultyLevel BETWEEN :minDifficulty AND :maxDifficulty")
    List<LearningExperience> findSimilarExperiences(@Param("lifeEntityId") Long lifeEntityId,
                                                    @Param("type") ExperienceType type,
                                                    @Param("minDifficulty") Integer minDifficulty,
                                                    @Param("maxDifficulty") Integer maxDifficulty);

    /**
     * 查找长时间未应用的经验
     */
    @Query("SELECT le FROM LearningExperience le WHERE le.lifeEntityId = :lifeEntityId AND (le.lastAppliedAt IS NULL OR le.lastAppliedAt < :threshold)")
    List<LearningExperience> findUnusedExperiences(@Param("lifeEntityId") Long lifeEntityId, 
                                                   @Param("threshold") LocalDateTime threshold);
}